<template>
  <m-modal
    ref="modalRef"
    :title="dialogTitle"
    :confirm-loading="confirmLoading"
    v-bind="option?.dialogProps || {}"
    :showOk="option?.showOk !== false && viewType!='view'"
    :showCancel="option?.showCancel !== false && viewType!='view'"
    @ok="handleOk"
    >
    <m-form ref="formRef" 
      :schema="formSchema" 
      :model="formState"
      v-bind="option?.formProps || {}"></m-form>
      <template #[key]="data" v-for="(item, key) in $slots">
        <slot :name="key" v-bind="data || {}"></slot>
      </template>
  </m-modal>
</template>
<script setup lang="ts">
import { PropType, computed, nextTick, reactive, ref, useSlots } from 'vue';
import { CrudType } from './types';
import { MFormItemType, MFormType } from '../Form/types';
import { postData } from '.';
import { message } from 'ant-design-vue';
import { isArray } from 'lodash-es';
const props = defineProps({
  option: {
    type: Object as PropType<CrudType>
  }
})
const emits = defineEmits(['save-success'])
const currentRow = ref()
const formRef = ref()
const confirmLoading = ref(false)
const slots = useSlots()
const modalRef = ref()
// 弹窗页面类型：add/edit/view
const viewType = ref('add')
const dialogTitle = computed(()=>{
  let text = '新增'
  if(viewType.value == 'edit'){
    text = '编辑'
  } else if(viewType.value == 'view'){
    text = '查看'
  }
  return `${text}${props.option?.title}`
})
// 表单列
const formColumns = computed<Array<MFormItemType>>(()=>{
  const res : Array<MFormItemType> = []
  props.option?.columns?.filter(column=> {
    if(viewType.value == 'edit') {
      return column.edit !==false
    } else if(viewType.value == 'view') {
      return column.view !==false
    }
    return column.add!==false
  }).forEach(column=>{
    const name = (column.key || column.dataIndex) as any
    let placeholder = '请输入' + column.title
    if(['Select', 'Dict'].includes(column.component as string)) {
      placeholder = '请选择'
    }
    const style = {} as any
    if(column.component == 'Input' && column.componentProps?.type == 'hidden') {
      style.display = 'none'
    }
    res.push({
      name: name,
      label: column.title as string,
      span: column.span,
      component: column.component as any,
      defaultValue: column.defaultValue,
      componentProps: {
        placeholder: placeholder,
        ...column.componentProps,
      },
      dynamicDisabled: column.dynamicDisabled,
      style: style,
      rules: column.rules,
      labelCol: column.labelCol,
      wrapperCol: column.wrapperCol,
      labelWidth: column.labelWidth,
      ...column.formColumnProps
    })
  })
  return res
})
/**
 * 获取表单默认值
 */
 const getFormDefaultValue = (columns: Array<MFormItemType>) =>{
  const v = {}
  columns.forEach(item=>{
    v[item.name as string] = item.defaultValue
  })
  return v;
}
// 表单数据
const formState = reactive({
  ...getFormDefaultValue(formColumns.value),
})
// 表单元数据
const formSchema = computed<MFormType>(()=>{
  return {
    columns: formColumns.value,
    showOk: false,
    showReset: false,
    ...props.option?.formProps
  }
})
// 表单提交处理
const handleOk = () => {
  formRef.value.validate().then((values: any)=>{
    confirmLoading.value = true;
    const postApi = viewType.value == 'edit' ? props.option?.updateApi : props.option?.saveApi
    postData(postApi,values).then(()=>{
      message.success(`${viewType.value == 'edit'?'更新成功！':'添加成功！'}`)
      // 通知父组件
      emits('save-success', values)
      // 重置表单
      formRef.value.resetFields();
      // 关闭弹窗
      modalRef.value.closeModal();
    }).finally(()=>{
      confirmLoading.value = false;
    })
  })
}
// 取消
const handleCancel = () =>{
  modalRef.value.closeModal();
}
defineExpose({
  openDialog(data: any,mViewType: string){
    viewType.value = mViewType
    currentRow.value = data;
    modalRef.value.openModal();
    nextTick(()=>{
      // 重置表单
      formRef.value.resetFields();
      // 重新赋值
      formRef.value.setFieldsValue(data)
      // 重新加载组件数据
      nextTick(()=>{
        props.option?.columns?.filter(column=>{
          return column?.componentProps?.immediate === false
        }).forEach(column=>{
          const componentRef = formRef?.value?.getComponentRef(column.key)
          const v = data?.[column.dataIndex as any]
          const includeIds: any = []
          if(v && isArray(v)) {
            includeIds.push(...v)
          } else if(v && !isArray(v)) {
            includeIds.push(v)
          }
          componentRef?.reload({
            includeType: 1,
            includeIds: includeIds
          })
        })
      })
    })
  },
  closeDialog(){
    modalRef.value.closeModal();
  },
  // 拿到表单操作句柄
  getFormRef() {
    return formRef.value
  }
})
</script>
<style lang="less" scoped>
.m-dialog-footer {
  display: flex;
  justify-content: end;
}
</style>